<script setup>
import {computed, ref} from 'vue'
import {useRoleForm} from '@/composables/roleManage/useRoleForm.js'
import {usePermissionDisplay} from '@/composables/roleManage/usePermissionDisplay.js'
import {useRoleOperations} from '@/composables/roleManage/useRoleOperations.js'
import {ElMessage, ElMessageBox} from 'element-plus'
import {saveAs} from 'file-saver'
import * as XLSX from 'xlsx'
import { mockUserData } from '@/mock/userMock.js'
import { useUserStore } from '@/stores/pages/user.js'

// 原始表格数据
const originalTableData = ref(mockUserData)

// 搜索结果数据
const searchResults = ref([])
// 是否正在加载
const loading = ref(false)
// 是否已执行过搜索
const hasSearched = ref(false)

// 表格引用
const tableRef = ref()

// 获取当前登录用户信息
const userStore = useUserStore()
const currentUser = computed(() => userStore.user || mockUserData[0])

// 当前用户不能对自身进行编辑和删除
const canOperate = (row) => {
  return row && row.id !== currentUser.value.id;
}

// 获取角色类型（element-plus tag类型）
const getRoleType = (roleName) => {
  switch (roleName) {
    case 'SUPER_ADMIN':
      return 'danger'  // 红色
    case 'ADMIN':
      return 'primary' // 蓝色
    case 'USER':
      return 'success' // 绿色
    default:
      return 'info'    // 灰色
  }
}

// 根据当前用户角色动态生成可选角色选项
const roleOptions = computed(() => {
  const options = [
    { label: "普通用户", value: "USER" },
    { label: "管理员", value: "ADMIN" }
  ];
  // 只有超级管理员才能分配超级管理员角色
  if (currentUser.value.roleName === 'SUPER_ADMIN') {
    options.unshift({ label: "超级管理员", value: "SUPER_ADMIN" });
  }
  return options;
});

// 格式化时间
const formatDateTime = (date) => {
  if (!date) return ''
  // 如果是字符串且已经符合格式，则直接返回
  if (typeof date === 'string' && date.includes('-') && date.includes(':')) {
    return date
  }
  // 否则格式化日期对象
  return new Date(date).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  }).replace(/\//g, '-').replace(',', '')
}

// 使用组合式函数
const {
  form: editForm,
  permissionTreeRef: editPermissionTreeRef,
  permissionTreeData: editPermissionTreeData,
  dialogVisible: editDialog,
  handleRoleChange: onRoleChange,
  handlePermissionCheck: onPermissionCheck,
  getCheckedPermissions: getEditCheckedPermissions,
  openDialog: openEditDialog
} = useRoleForm('edit')

const {
  form: addForm,
  formRef: addFormRef,
  permissionTreeRef: addPermissionTreeRef,
  permissionTreeData: addPermissionTreeData,
  dialogVisible: addDialog,
  handleRoleChange: onAddRoleChange,
  handlePermissionCheck: onAddPermissionCheck,
  getCheckedPermissions: getAddCheckedPermissions,
  openDialog: openAddDialog
} = useRoleForm('add')

const {
  getPermissionColor,
  groupPermissions,
  isFewPermissions,
  processPermissionsDisplay
} = usePermissionDisplay()

const {
  saveRole
} = useRoleOperations(originalTableData, searchResults, hasSearched, formatDateTime)

// 搜索关键字
const input = ref('')

// 计算属性：根据状态返回显示的数据
const tableData = computed(() => {
  // 如果还没搜索过，显示所有数据
  if (!hasSearched.value) {
    return originalTableData.value
  }
  // 如果搜索过，显示搜索结果
  return searchResults.value
})

// 执行搜索
const performSearch = () => {
  loading.value = true

  // 模拟网络延迟
  setTimeout(() => {
    if (!input.value) {
      // 如果搜索关键字为空，显示所有数据
      searchResults.value = originalTableData.value
    } else {
      const keyword = input.value.toLowerCase().trim()
      searchResults.value = originalTableData.value.filter(item =>
          item.username.toLowerCase().includes(keyword) ||
          item.roleName.toLowerCase().includes(keyword) ||
          item.description.toLowerCase().includes(keyword)
      )
    }

    hasSearched.value = true
    loading.value = false
  }, 300) // 模拟300ms的网络延迟
}

// 处理搜索
const searchHandle = () => {
  performSearch()
}

// 处理回车键搜索
const handleKeyDown = (event) => {
  if (event.key === 'Enter') {
    performSearch()
  }
}

// 简化后的操作函数
const handleEdit = (row) => {
  if (!canOperate(row)) return
  openEditDialog(row)
}

// 获取用户选项列表
const userOptions = computed(() => {
  // 从用户模拟数据中获取所有用户
  return mockUserData.map(user => ({
    label: user.username,
    value: user.id
  }))
})

// 处理添加角色（实际上是为现有用户分配角色）
const handleAdd = () => {
  // 重置表单
  addForm.value = {
    userId: null,
    username: '',
    roleName: 'USER',
    description: '',
    permissions: [],
    status: 1
  }
  addDialog.value = true
}

const handleSave = async () => {
  const success = await saveRole(editForm, true, editForm.id)
  if (success) {
    editDialog.value = false
  }
}

const handleAddSave = async () => {
  if (!addFormRef.value) return

  try {
    await addFormRef.value.validate()
    const success = await saveRole(addForm, false)
    if (success) {
      addDialog.value = false
    }
  } catch (error) {
    ElMessage.error('表单验证失败，请检查输入')
  }
}

// 删除角色
const handleDelete = (row) => {
  if (!canOperate(row)) return

  ElMessageBox.confirm(
      `确定要删除角色 "${row.roleName}" 吗？此操作不可恢复。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(() => {
    // 模拟API调用删除角色
    // 实际项目中这里应该是:
    // await roleApi.deleteRole(row.id)

    // 从原始数据中移除
    const index = originalTableData.value.findIndex(item => item.id === row.id)
    if (index !== -1) {
      originalTableData.value.splice(index, 1)
    }

    // 如果已经搜索过，也需要从搜索结果中移除
    if (hasSearched.value) {
      const searchIndex = searchResults.value.findIndex(item => item.id === row.id)
      if (searchIndex !== -1) {
        searchResults.value.splice(searchIndex, 1)
      }
    }

    ElMessage.success('角色删除成功')
  }).catch(() => {
    // 用户取消删除
    ElMessage.info('已取消删除')
  })
}

// 批量删除角色
const handleBatchDelete = () => {
  // 获取选中的行
  const selectedRows = tableRef.value.getSelectionRows()

  // 检查是否有选中的行
  if (selectedRows.length === 0) {
    ElMessage.warning('请至少选择一个角色进行删除')
    return
  }

  // 过滤掉不能操作的行（当前用户）
  const deletableRows = selectedRows.filter(row => canOperate(row))

  // 检查是否有可删除的行
  if (deletableRows.length === 0) {
    ElMessage.warning('没有可删除的角色')
    return
  }

  // 检查是否有不能删除的行
  const nonDeletableRows = selectedRows.filter(row => !canOperate(row))
  if (nonDeletableRows.length > 0) {
    ElMessage.warning('不能删除当前用户角色')
  }

  // 确认删除
  ElMessageBox.confirm(
      `确定要删除选中的 ${deletableRows.length} 个角色吗？此操作不可恢复。`,
      '确认批量删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(() => {
    // 删除选中的行
    deletableRows.forEach(row => {
      // 从原始数据中移除
      const index = originalTableData.value.findIndex(item => item.id === row.id)
      if (index !== -1) {
        originalTableData.value.splice(index, 1)
      }

      // 如果已经搜索过，也需要从搜索结果中移除
      if (hasSearched.value) {
        const searchIndex = searchResults.value.findIndex(item => item.id === row.id)
        if (searchIndex !== -1) {
          searchResults.value.splice(searchIndex, 1)
        }
      }
    })

    // 清除选中状态
    tableRef.value.clearSelection()

    ElMessage.success(`成功删除 ${deletableRows.length} 个角色`)
  }).catch(() => {
    // 用户取消删除
    ElMessage.info('已取消批量删除')
  })
}

// 导出数据为Excel
const exportData = () => {
  // 确定要导出的数据
  let dataToExport = []
  const selectedRows = tableRef.value.getSelectionRows()

  // 如果有选中的行，只导出选中的行；否则导出当前显示的所有数据
  if (selectedRows.length > 0) {
    dataToExport = selectedRows
  } else {
    dataToExport = tableData.value
  }

  // 如果没有数据可导出
  if (dataToExport.length === 0) {
    ElMessage.warning('没有数据可导出')
    return
  }

  // 弹出确认框
  ElMessageBox.confirm(
    `确定要导出${dataToExport.length}条数据吗？`,
    '导出确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    try {
      // 处理数据格式
      const processedData = dataToExport.map(item => {
        return {
          'ID': item.id,
          '用户名': item.username,
          '角色名': item.roleName,
          '描述': item.description,
          '权限列表': Array.isArray(item.permissions) ? item.permissions.join(';') : item.permissions,
          '状态': item.status === 1 ? '启用' : '禁用',
          '创建时间': item.createTime,
          '更新时间': item.updateTime
        }
      })

      // 使用xlsx库创建Excel文件
      const ws = XLSX.utils.json_to_sheet(processedData)
      const wb = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(wb, ws, '角色数据')
      
      // 设置列宽
      ws['!cols'] = [
        {wch: 10}, // ID
        {wch: 15}, // 用户名
        {wch: 15}, // 角色名
        {wch: 25}, // 描述
        {wch: 40}, // 权限列表
        {wch: 10}, // 状态
        {wch: 20}, // 创建时间
        {wch: 20}  // 更新时间
      ]

      // 写入Excel文件并导出
      const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
      const blob = new Blob([excelBuffer], { type: 'application/octet-stream' })
      const fileName = `角色数据_${new Date().toISOString().slice(0, 10)}.xlsx`
      saveAs(blob, fileName)

      ElMessage.success(`成功导出 ${dataToExport.length} 条数据`)
    } catch (error) {
      console.error('导出失败:', error)
      ElMessage.error('导出失败: ' + error.message)
    }
  }).catch(() => {
    ElMessage.info('已取消导出')
  })
}

// 处理用户选择变化
const handleUserChange = (userId) => {
  // 根据选中的用户ID查找用户信息
  const user = mockUserData.find(u => u.id === userId)
  if (user) {
    addForm.value.username = user.username
    // 可以根据需要设置其他默认值
  }
}
</script>
<template>
  <div class="role-management-container">
    <el-card style="max-width:100%">
      <template #header>
        <div class="card-header">
          <el-input
              v-model="input"
              style="width: 250px"
              placeholder="请输入用户名/角色名/描述"
              @keydown="handleKeyDown"
          />
          <el-button
              style="margin-left: 10px"
              type="primary"
              @click="searchHandle"
              :loading="loading"
          >
            {{ loading ? '搜索中...' : '搜索' }}
          </el-button>
          <el-button type="success" @click="handleAdd">分配角色</el-button>
          <el-button type="danger" @click="handleBatchDelete">批量删除</el-button>
          <el-button type="primary" @click="exportData">导出</el-button>
        </div>
      </template>

      <el-table
          :data="tableData"
          stripe
          height="500px"
          style="width: 100%"
          border="border"
          v-loading="loading"
          ref="tableRef"
      >
        <el-table-column type="selection" width="50px" align="center"/>
        <el-table-column prop="id" label="序号" width="70" fixed="left" align="center"/>
        <el-table-column prop="username" label="用户名" width="120" fixed="left"/>
        <el-table-column prop="roleName" label="角色" width="130">
          <template #default="{row}">
            <el-tag :type="getRoleType(row.roleName)">
              {{ row.roleName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" width="160"/>
        <el-table-column prop="permissions" label="权限列表" width="220">
          <template #default="{row}">
            <!-- 确保权限数据有效 -->
            <div :data-permissions="Array.isArray(row.permissions) ? row.permissions.length : 'invalid'">
            <!-- 权限少：直接显示标签 -->
            <div v-if="isFewPermissions(processPermissionsDisplay(row.permissions))" class="permissions-tags">
              <el-tag
                  class="permission-tag"
                  v-for="permission in processPermissionsDisplay(row.permissions)"
                  :key="permission"
                  size="small"
                  :type="getPermissionColor(permission)"
              >
                {{ permission }}
              </el-tag>
            </div>

            <!-- 权限多或权限数据无效：Popover显示 -->
            <el-popover 
              v-else 
              placement="right" 
              :width="350" 
              trigger="hover"
              :disabled="!row.permissions || !Array.isArray(row.permissions)">
              <template #reference>
                <span class="popover-tips">悬浮查看权限详情</span>
              </template>

              <div class="permissions-popover-content">
                <div class="popover-header">
                  <span>权限详情</span>
                  <span class="permission-count">共{{ (row.permissions && row.permissions.length) || 0 }}个</span>
                </div>

                <!-- 分组显示权限 -->
                <div
                    v-for="(permissions, groupName) in groupPermissions(processPermissionsDisplay(row.permissions))"
                    :key="groupName"
                    class="permission-group"
                >
                  <div class="group-header">
                    <span class="group-title">{{ groupName }} 权限</span>
                    <span class="group-count">{{ (permissions && permissions.length) || 0 }}个</span>
                  </div>
                  <div class="permissions-tags">
                    <el-tag
                        class="permission-tag"
                        v-for="permission in permissions"
                        :key="permission"
                        size="small"
                        :type="getPermissionColor(permission)"
                    >
                      {{ permission && permission.split ? permission.split(':')[1] : permission }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </el-popover>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="70" align="center">
          <template #default="{row}">
            <el-tag :type="row.status ? 'success' : 'danger'">
              {{ row.status ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="185"/>
        <el-table-column prop="updateTime" label="更新时间" width="185"/>
        <el-table-column fixed="right" label="操作" min-width="140">
          <template #default="{row}">
            <el-button link type="primary" size="small" :disabled="!canOperate(row)" @click="handleEdit(row)">编辑
            </el-button>
            <el-button link type="danger" size="small" :disabled="!canOperate(row)" @click="handleDelete(row)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 编辑对话框 -->
    <el-dialog v-model="editDialog" width="550" title="编辑角色">
      <el-form :model="editForm" label-width="auto">
        <el-form-item label="角色">
          <el-select
              v-model="editForm.roleName"
              placeholder="请选择角色"
              @change="onRoleChange"
          >
            <el-option
                v-for="option in roleOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value"/>
          </el-select>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="editForm.description" placeholder="请输入角色描述"/>
        </el-form-item>
        <el-form-item label="权限列表">
          <div class="permission-tree-container">
            <div class="permission-tips">
              <el-text type="info" size="small">
                已选择 {{ getEditCheckedPermissions().length }} 个权限
              </el-text>
            </div>
            <div class="permission-tree-content">
              <el-tree
                  ref="editPermissionTreeRef"
                  :data="editPermissionTreeData"
                  show-checkbox
                  node-key="value"
                  :default-checked-keys="getEditCheckedPermissions()"
                  :props="{
                  children: 'children',
                  label: 'label'
                }"
                  @check="onPermissionCheck"
              />
            </div>
          </div>
        </el-form-item>
        <el-form-item label="状态">
          <el-switch v-model="editForm.status"/>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSave">保存</el-button>
          <el-button @click="editDialog = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 添加对话框（改为分配角色） -->
    <el-dialog v-model="addDialog" width="550" title="分配角色">
      <el-form
          :model="addForm"
          ref="addFormRef"
          label-width="auto">
        <el-form-item
            label="用户"
            prop="userId"
            :rules="[{ required: true, message: '请选择用户', trigger: 'change' }]">
          <el-select
              v-model="addForm.userId"
              placeholder="请选择用户"
              @change="handleUserChange"
          >
            <el-option
                v-for="option in userOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
            label="角色"
            prop="roleName"
            :rules="[{ required: true, message: '请选择角色', trigger: 'change' }]">
          <el-select
              v-model="addForm.roleName"
              placeholder="请选择角色"
              @change="onAddRoleChange"
          >
            <el-option
                v-for="option in roleOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value"/>
          </el-select>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="addForm.description" placeholder="请输入角色描述"/>
        </el-form-item>
        <el-form-item
            label="权限列表"
            prop="permissions"
            :rules="[{ required: true, message: '请至少选择一个权限', trigger: 'change' }]">
          <div class="permission-tree-container">
            <div class="permission-tips">
              <el-text type="info" size="small">
                已选择 {{ getAddCheckedPermissions().length }} 个权限
              </el-text>
            </div>
            <div class="permission-tree-content">
              <el-tree
                  ref="addPermissionTreeRef"
                  :data="addPermissionTreeData"
                  show-checkbox
                  node-key="value"
                  :default-checked-keys="addForm.permissions"
                  :props="{
                  children: 'children',
                  label: 'label'
                }"
                  @check="onAddPermissionCheck"
              />
            </div>
          </div>
        </el-form-item>
        <el-form-item label="状态">
          <el-switch v-model="addForm.status"/>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleAddSave">保存</el-button>
          <el-button @click="addDialog = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<style scoped>
.card-header {
  display: flex;
  flex-wrap: nowrap;
}

.popover-tips {
  cursor: pointer;
  color: #409eff;
  padding: 4px 8px;
  border-radius: 4px;
  background: #f0f9ff;
  font-size: 12px;
  transition: all 0.3s;
}

.permissions-popover-content {
  max-height: 400px;
  overflow-y: auto;
}

.popover-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e4e7ed;
  font-size: 14px;
  font-weight: 500;
}

.permission-group {
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px dashed #ebeef5;
}

.permission-group:last-child {
  border-bottom: none;
  margin-bottom: 0;
}

.group-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.group-title {
  font-size: 13px;
  font-weight: 600;
  color: #606266;
  text-transform: capitalize;
}

.group-count {
  font-size: 12px;
  color: #909399;
  background: #f4f4f5;
  padding: 2px 6px;
  border-radius: 10px;
}

.permissions-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.permission-tag {
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.permission-tree-container {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 12px;
  max-height: 300px;
  display: flex;
  flex-direction: column;
}

.permission-tree-content {
  flex: 1;
  overflow-y: auto;
  width: 250px;
}

.permission-tips {
  padding-bottom: 8px;
  border-bottom: 1px dashed #e4e7ed;
  margin-bottom: 8px;
}
</style>